On 7 November 2014 20:22, Ashwin Chaugule ashwin.chaugule@linaro.org wrote:
+struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
int index)
+{
struct device *dev = pcc_mbox_ctrl.dev;
struct mbox_chan *chan;
unsigned long flags;
/*
* Each PCC Subspace is a Mailbox Channel.
* The PCC Clients get their PCC Subspace ID
* from their own tables and pass it here.
* This returns a pointer to the PCC subspace
* for the Client to operate on.
*/
chan = &pcc_mbox_chan[index];
You are mapping 'Type' of a client directly onto SubSpace-ID of the channel allocated. If two clients need an instance of, say, Generic-Communications-Channel i.e, Type-0, this will not work. If no two clients can ask the same channel, MAX_PCC_SUBSPACES should be limited to max 'Type' value defined in ACPI specs (just 2 in ACPI-5.1).
if (!chan || chan->cl) {
dev_err(dev, "%s: PCC mailbox not free\n", __func__);
return ERR_PTR(-EBUSY);
}
spin_lock_irqsave(&chan->lock, flags);
chan->msg_free = 0;
chan->msg_count = 0;
chan->active_req = NULL;
chan->cl = cl;
init_completion(&chan->tx_complete);
if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
chan->txdone_method |= TXDONE_BY_ACK;
spin_unlock_irqrestore(&chan->lock, flags);
return chan;
+} +EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
Nothing PCC specific here. All you have done is define a new api just to pick an element from the array. You simply needed the mbox_request_channel() let you through to controller.
+void pcc_mbox_free_channel(struct mbox_chan *chan) +{
unsigned long flags;
if (!chan || !chan->cl)
return;
spin_lock_irqsave(&chan->lock, flags);
chan->cl = NULL;
chan->active_req = NULL;
if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
chan->txdone_method = TXDONE_BY_POLL;
spin_unlock_irqrestore(&chan->lock, flags);
+} +EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
Ditto, nothing PCC in this new PCC specific api.
+/**
- pcc_send_data - Called from Mailbox Controller code to finally
transmit data over channel.
- @chan: Pointer to Mailbox channel over which to send data.
- @data: Actual data to be written over channel.
- Return: Err if something failed else 0 for success.
- */
+static int pcc_send_data(struct mbox_chan *chan, void *data) +{
struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv;
struct acpi_pcct_shared_memory *generic_comm_base =
(struct acpi_pcct_shared_memory *) pcct_ss->base_address;
struct acpi_generic_address doorbell;
u64 doorbell_preserve;
u64 doorbell_val;
u64 doorbell_write;
u16 cmd = *(u16 *) data;
u16 ss_idx = -1;
ss_idx = get_subspace_id(chan);
if (ss_idx < 0) {
pr_err("Invalid Subspace ID from PCC client\n");
return -EINVAL;
}
doorbell = pcct_ss->doorbell_register;
doorbell_preserve = pcct_ss->preserve_mask;
doorbell_write = pcct_ss->write_mask;
/* Write to the shared comm region. */
writew(cmd, &generic_comm_base->command);
/* Write Subspace MAGIC value so platform can identify destination. */
writel((PCCS_SS_SIG_MAGIC | ss_idx), &generic_comm_base->signature);
/* Flip CMD COMPLETE bit */
writew(0, &generic_comm_base->status);
/* Sync notification from OSPM to Platform. */
acpi_read(&doorbell_val, &doorbell);
acpi_write((doorbell_val & doorbell_preserve) | doorbell_write,
&doorbell);
return 0;
+}
+static struct mbox_chan_ops pcc_chan_ops = {
.send_data = pcc_send_data,
.last_tx_done = pcc_tx_done,
+};
+/**
- parse_pcc_subspace - Parse the PCC table and extract PCC subspace
entries. There should be one entry per PCC client.
- @header: Pointer to the ACPI subtable header under the PCCT.
- @end: End of subtable entry.
- Return: 0 for Success, else errno.
- This gets called for each entry in the PCC table.
- */
+static int parse_pcc_subspace(struct acpi_subtable_header *header,
const unsigned long end)
+{
struct acpi_pcct_hw_reduced *pcct_ss;
if (pcc_mbox_ctrl.num_chans <= MAX_PCC_SUBSPACES) {
pcct_ss = (struct acpi_pcct_hw_reduced *) header;
if (pcct_ss->header.type !=
ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) {
pr_err("Incorrect PCC Subspace type detected\n");
return -EINVAL;
}
The driver supports only ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE client ?!
-Jassi